#ifndef MATERIALVIEWITEMS_H
#define MATERIALVIEWITEMS_H

#include <baseitemmodel.h>
#include <grouptreeitem.h>
#include <materialmanager.h>



class MaterialView;
class CategoryItem : public BaseItem
{
private:
  MaterialView*         _view;
  Category              _category;

  QList<CategoryItem*>  _children;
  CategoryItem*         _parent;

  bool                  _editable;
private:
  bool IsEmpty () const;

protected:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

  void SetEditable (bool editable);

public:
  CategoryItem (MaterialView* view, const Category& item);

  bool IsEditable () const;

  /** Adds a new category item and adds */
  void AddGroup (CategoryItem *item);
  /** Removes an existing category group */
  void RemoveGroup (CategoryItem *item);

  /** Gets a category item with the given name. If no such category exists a new one is create */
  CategoryItem* Get (const QString& name);

  /** Removes all empty categorys and removes this if it is emtpy */
  void Cleanup ();


  virtual QVariant GetData (int column, int role);


  MaterialView* GetView ();
  /** Returns the category of this item */
  Category& GetCategory ();
  const QString& GetName () const;

  virtual QString GetTypeName () const { return "CategoryItem"; }

  virtual void EnableActions();
  virtual bool BuildMenu(QMenu *menu);

};



class MaterialDataItem : public BaseItem
{
private:
  MaterialData* _data;

  MaterialView* _view;

protected:
  MaterialDataItem (MaterialData* data, MaterialView* view);

public:
  MaterialView* GetView ();
  MaterialData* GetMaterialData ();

  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
};


/* ***************************
 *  Texture Items
 * ***************************/

class TextureCategoryItem : public CategoryItem
{
private:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

public:
  TextureCategoryItem (MaterialView* view, const Category& item, bool editable);
  virtual void EnableActions();
  virtual bool BuildMenu (QMenu* menu);

  virtual QString GetTypeName () const { return "TextureCategoryItem"; }

};

class TextureItem : public MaterialDataItem
{
private:
  Texture*        _texture;
public:
  TextureItem (MaterialView* view, Texture* texture);
  Texture* GetTexture ();

  QVariant GetData (int column, int role);
  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
  void Trigger ();

  virtual QString GetTypeName () const { return "TextureItem"; }

};

/* ***************************
 *  Shader Items
 * ***************************/

class ShaderCategoryItem : public CategoryItem
{
private:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

public:
  ShaderCategoryItem (MaterialView* view, const Category& item, bool editable);
  virtual void EnableActions();
  virtual bool BuildMenu (QMenu* menu);

  virtual QString GetTypeName () const { return "ShaderCategoryItem"; }

};



class ShaderItem : public MaterialDataItem
{
private:
  Shader*        _shader;
public:
  ShaderItem (MaterialView* view, Shader* shader);
  Shader* GetShader ();

  QVariant GetData (int column, int role);
  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
  void Trigger ();

  virtual QString GetTypeName () const { return "ShaderItem"; }

};


/* ***************************
 *  Program Items
 * ***************************/

class ProgramCategoryItem : public CategoryItem
{
private:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

public:
  ProgramCategoryItem (MaterialView* view, const Category& item, bool editable);
  virtual void EnableActions();
  virtual bool BuildMenu (QMenu* menu);

  virtual QString GetTypeName () const { return "ProgramCategoryItem"; }

};



class ProgramItem : public MaterialDataItem
{
private:
  Program*        _program;
public:
  ProgramItem (MaterialView* view, Program* program);
  Program* GetProgram ();

  QVariant GetData (int column, int role);
  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
  void Trigger ();

  virtual QString GetTypeName () const { return "ProgramItem"; }

};


/* ***************************
 *  Effect Items
 * ***************************/

class EffectCategoryItem : public CategoryItem
{
private:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

public:
  EffectCategoryItem (MaterialView* view, const Category& item, bool editable);
  virtual void EnableActions();
  virtual bool BuildMenu (QMenu* menu);

  virtual QString GetTypeName () const { return "EffectCategoryItem"; }

};



class EffectItem : public MaterialDataItem
{
private:
  Effect*        _effect;
public:
  EffectItem (MaterialView* view, Effect* effect);
  Effect* GetEffect ();

  QVariant GetData (int column, int role);
  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
  void Trigger ();

  virtual QString GetTypeName () const { return "EffectItem"; }

};




/* ***************************
 *  Material Items
 * ***************************/

class MaterialCategoryItem : public CategoryItem
{
private:
  virtual CategoryItem* CreateNewItem (MaterialView* view, const Category& item);

public:
  MaterialCategoryItem (MaterialView* view, const Category& item, bool editable);
  virtual void EnableActions();
  virtual bool BuildMenu (QMenu* menu);

  virtual QString GetTypeName () const { return "MaterialCategoryItem"; }

};



class MaterialItem : public MaterialDataItem
{
private:
  Material*        _material;
public:
  MaterialItem (MaterialView* view, Material* material);
  Material* GetMaterial ();

  QVariant GetData (int column, int role);
  virtual void EnableActions();
  bool BuildMenu (QMenu* menu);
  void Trigger ();

  virtual QString GetTypeName () const { return "MaterialItem"; }

};

#endif // MATERIALVIEWITEMS_H
